package com.mk.settlement.kafka;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.mk.kafka.client.stereotype.MkMessageService;
import com.mk.kafka.client.stereotype.MkTopicConsumer;
import com.mk.settlement.enums.DefaultRelationEnums;
import com.mk.settlement.enums.SettlementStateEnums;
import com.mk.settlement.model.Order;
import com.mk.settlement.model.SettlementOrder;
import com.mk.settlement.model.SettlementRule;
import com.mk.settlement.service.SettlementService;
@Service
@MkMessageService
public class SettlementKafkaConsumer {

	private Logger logger = LoggerFactory.getLogger(SettlementKafkaConsumer.class);
	
	@Autowired
	private SettlementService settlementService;
	
	@MkTopicConsumer(topic = "standard_test_topic", group = "standard_test_topic_g", serializerClass = "com.mk.kafka.client.serializer.StringDecoder")
	public void consume(String data) {
		logger.info("StandardKafkaConsumer consume a message:" + data);
	}
	
	@MkTopicConsumer(topic = "order_order_left", group = "settlement_order_g", serializerClass = "com.mk.kafka.client.serializer.StringDecoder")
	public void orderConsume(String orderJson) {
		
//例:	orderJson = "{"hotelid":1308,"hotelname":"闲庭假日宾馆","hprice":70.00,"otaid":1,
//	         "otaname":"眯客","oprice":70.00,"orderid":1016,"paytype":1,"checkouttime":"","saletype":"1"}";
		logger.info("从kafka接收到的消息:" + orderJson);
		
		Order order = null;
        try {
            order = JSON.parseObject(orderJson, Order.class);
        } catch (Exception e) {
            logger.error("反序列化消息异常!", e);
        }
		Long orderid = order.getOrderid();
		Integer saletype = order.getSaletype();
		Integer settlementState = SettlementStateEnums.NotStatistics.getIndex(); //默认 未统计
		String paytype = "%"+order.getPayType() +"%";
		
		//计算酒店金额
		Long hotelid = order.getHotelid();
		List<SettlementRule> hrule = getRule(hotelid, paytype, order.getHotelname(), DefaultRelationEnums.HOTEL.getMark());
		for (SettlementRule settlementRule : hrule) {
			String feeRule = settlementRule.getFeeRule();
			SettlementOrder hsettlementOrder = new SettlementOrder();
			try {
				BigDecimal settlementSum = getSettlementSum(feeRule, order);
				hsettlementOrder.setSettlementSum(settlementSum);
			} catch (Exception e) {
				logger.error("hotelid : " + hotelid + " , 获取规则出错.", e);
			}
			
			hsettlementOrder.setOrderId(orderid);
			hsettlementOrder.setOriginalSum(order.getHprice());
			hsettlementOrder.setSettlementTargetId(hotelid);
			hsettlementOrder.setSettlementTargetName(order.getHotelname());
			hsettlementOrder.setFeeType(settlementRule.getFeeType());
			if(saletype == null){
				saletype = 1;
			}
			hsettlementOrder.setSaleType(saletype);
			hsettlementOrder.setSettlementCategory(settlementRule.getSettlementCategory());
			hsettlementOrder.setSettlementRuleId(settlementRule.getId());
			hsettlementOrder.setSettlementState(settlementState);
			hsettlementOrder.setSettlementType(settlementRule.getSettlementType());
			hsettlementOrder.setCreateTime(new Date());
			hsettlementOrder.setUpdateTime(new Date());
			//根据结算类型 计算 本条记录结算时间
			String settlementTypeRule = settlementRule.getSettlementTypeRule();
			if(order.getCheckouttime() == null){
				order.setCheckouttime(new Date());
			}
			Date settlementTime = getSettlementTime(settlementTypeRule, order);
			hsettlementOrder.setSettlementTime(settlementTime);
			
			addSettlementOrder(hsettlementOrder);
		}
		//计算ota金额
		Long otaid = order.getOtaid();
		List<SettlementRule> orule = getRule(otaid, paytype, order.getOtaname(), DefaultRelationEnums.OTA.getMark());
		for (SettlementRule settlementRule : orule) {
			String feeRule = settlementRule.getFeeRule();
			SettlementOrder osettlementOrder = new SettlementOrder();
			try {
				BigDecimal settlementSum = getSettlementSum(feeRule, order);
				osettlementOrder.setSettlementSum(settlementSum);
			} catch (Exception e) {
				logger.error("otaid : " + otaid + " , 获取规则出错.", e);
			}
			
			osettlementOrder.setOrderId(orderid);
			osettlementOrder.setOriginalSum(order.getOprice());
			osettlementOrder.setSettlementTargetId(otaid);
			osettlementOrder.setSettlementTargetName(order.getOtaname());
			osettlementOrder.setFeeType(settlementRule.getFeeType());
			osettlementOrder.setSaleType(saletype);
			osettlementOrder.setSettlementCategory(settlementRule.getSettlementCategory());
			osettlementOrder.setSettlementRuleId(settlementRule.getId());
			osettlementOrder.setSettlementState(settlementState);
			osettlementOrder.setSettlementType(settlementRule.getSettlementType());
			osettlementOrder.setCreateTime(new Date());
			osettlementOrder.setUpdateTime(new Date());
			//根据结算类型 计算 本条记录结算时间
			String settlementTypeRule = settlementRule.getSettlementTypeRule();
			if(order.getCheckouttime() == null){
				order.setCheckouttime(new Date());
			}
			Date settlementTime = getSettlementTime(settlementTypeRule, order);
			osettlementOrder.setSettlementTime(settlementTime);
			
			addSettlementOrder(osettlementOrder);
		}
		
	}
	
	//查询hotel或ota的结算规则 
	public List<SettlementRule> getRule(Long settlementTargetId, String paytype, String name, String mark){
		if(settlementTargetId == null){
			logger.error("settlementTargetId == null 酒店或者otaid 不能为空");
			
			return null;
		}
		List<SettlementRule> settlementRules = settlementService.getSettlementRulesByTarId(settlementTargetId, paytype);
		if(settlementRules == null || settlementRules.size() == 0){
			logger.error("酒店或者otaid : " + settlementTargetId + " 没有对应的结算规则");
			logger.info("settlementTargetId:" + settlementTargetId + ",name:" + name + ",mark" + mark +"使用默认的结算规则.");
			
			settlementRules = settlementService.getRulesByIds(DefaultRelationEnums.getDefaultRuleId(mark));
			
			logger.info("settlementTargetId:" + settlementTargetId + ",name:" + name + ",mark" + mark +"初始化关系为默认的结算规则.");
			settlementService.insertDefaultRelation(settlementTargetId, name, mark);
		}
		return settlementRules;
	}
	
	//计算hotel或者ota 各种需结算金额
	public BigDecimal getSettlementSum(String feeRule, Order order){
        ExpressionParser parser = new SpelExpressionParser();
        Expression exp = parser.parseExpression(feeRule);

        EvaluationContext context = new StandardEvaluationContext(order);
        return exp.getValue(context, BigDecimal.class);
	}
	
	//计算hotel或者ota 各种需结算日期
	public Date getSettlementTime(String settlementTypeRule, Order order){
		try {
			ExpressionParser parser = new SpelExpressionParser();
			org.springframework.expression.Expression exp = parser.parseExpression(settlementTypeRule);
			
			EvaluationContext context = new StandardEvaluationContext(order);
			return (Date) exp.getValue(context);
		} catch (Exception e) {
			logger.error("获取结算时间出错！", e);
			return null;
		}
	}
	
	//向 结算基础数据 订单结算表 添加数据
	public void addSettlementOrder(SettlementOrder settlementOrder){
		settlementService.addSettlementOrder(settlementOrder);
	}

}
